# 继承和重写

# 单继承
# class Animal(object):
#     name = '动物'
#
#     def say(self):
#         print('动物的叫声')
#
#
# class Dog(Animal):  # 单继承，子类只继承一个父类
#
#     def see_home(self):
#         print('狗看家')
#
#
# d = Dog()
# # d.see_home()
# # d.say()
# # print(d.name)
#
# # 子类的对象 是子类类型，同时也是父类类型
# print(type(d))
# print(isinstance(d, Dog))  # 这个方法就是判断d这个对象是不是Dog类型
# print(isinstance(d, Animal))  # 结果为True，说明子类对象 既是子类类型，也是父类类型
# # 下面这个方法是判断两个类之间有没有继承关系（第一个参数是子类，第二个参数是父类）
# print(issubclass(Dog, Animal))


# 函数的重写
# class Parent:  # 可以省略 (object)
#
#     def __init__(self, name):
#         self.name = name
#         print('parent的init函数被执行')
#
#     def say_hello(self):
#         print(f'{self.name}: hello')
#         print('Parent的say_hello函数被执行')
#
#
# class Son(Parent):
#
#     def __init__(self, name, age):
#         # self.name = name
#         super().__init__(name)  # 通过super调用父类中的这个函数简化代码重复使用
#         self.age = age
#         print('Son的init函数被执行')
#
#     def say_hello(self):
#         print(f'{self.name}: hello world!')
#         print('Son的say_hello函数被执行')
#
#
# s1 = Son('张三', 25)
# s1.say_hello()


# 多继承
# class Parent(object):
#
#     def __init__(self, name, *args, **kwargs):
#         self.name = name
#         print('Parent的init函数执行')
#
#     def test(self):
#         print('Parent的test函数执行')
#
#
# class Son1(Parent):
#
#     def __init__(self, name, age, *args, **kwargs):
#         self.age = age
#         super().__init__(name, *args, **kwargs)
#         print('Son1的init函数执行')
#
#     def test(self):
#         print('Son1的test函数执行')
#
#
# class Son2(Parent):
#
#     def __init__(self, name, sex, *args, **kwargs):
#         self.sex = sex
#         super().__init__(name, *args, **kwargs)
#         print('Son2的init函数执行')
#
#     def test(self):
#         print('Son2的test函数执行')
#
#
# class GrandSon(Son1, Son2):  # 多继承，继承多个父类
#
#     def __init__(self, name, age, sex, *args, **kwargs):
#         super().__init__(name, age, sex)
#         print('GrandSon的init函数执行')
#
# print(f'MRO序列是：{GrandSon.__mro__}')
# gs = GrandSon('张三', 32, '男')
# gs.test()  # 先Son1 中找到了test函数，就不会在Son2中继续找了


# 私有属性和方法
# class Animal(object):
#
#     __name = '动物'  # 私有属性（类属性）
#
#     def __init__(self, color):
#         self.__color = color  # 对象的私有属性
#
#     def __run(self):  # 私有函数
#         print(self.__name)  # 类里面可以访问私有属性
#         print('动物吃肉')
#
#     def say(self):  # 普通函数
#         self.__run()  # 在类里面调用私有方法
#         print('叫什么叫')
#         # print(self.__color)
#
#     def set_color(self, new_color):  # 通过提供set_xx函数修改私有属性
#         self.__color = new_color
#
#     def get_color(self):
#         return self.__color
#
# class Dog(Animal):
#     pass
#
#
# d1 = Dog('red')
# d1.set_color('green')
# d1.say()
# print(d1.get_color())
# # d1.__run()
# # d1.run()


# 多态
class Animal(object):

    def say(self):
        pass


class Dog(Animal):
    def say(self):
        print('Dog says')


class Cat(Animal):

    def say(self):
        print('Cat says')


def test(obj):
    obj.say()


d = Dog()
c = Cat()

test(d)
test(c)
